package knowlwdge_graph.knowledge_etl.yago_etl;

import common.dao.orient.OrientJDBCDao;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.Statement;

/**
 * Created by julianzliu on 4/17/2017.
 */
public class SchemaConstructer {

    static final org.slf4j.Logger logger = LoggerFactory.getLogger(SchemaConstructer.class);

    private OrientJDBCDao orientJDBCDao;
    private Connection conn;

    public SchemaConstructer(){
        this.orientJDBCDao = new OrientJDBCDao();
        this.conn = this.orientJDBCDao.getConn();

    }

    private boolean createSchema(String sql){
        logger.info("[createSchema] sql = {}", sql );

        Statement stmt = null;
        boolean success = true;
        try {
            stmt = this.conn.createStatement();
            success = stmt.execute(sql);
            stmt.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return success;
    }



    /*
    LABEL
     */
    public boolean createYAGO_LABEL_CLASS(){
        boolean success = true;
        String sql = "";

        sql = String.format("CREATE CLASS %s EXTENDS V", SchemaDefinition.YAGO_LABEL_CLASS.CLASS_NAME);
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_LABEL_CLASS.CLASS_NAME,SchemaDefinition.YAGO_LABEL_CLASS.PROPERTY_YAGO_ID );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_LABEL_CLASS.CLASS_NAME,SchemaDefinition.YAGO_LABEL_CLASS.PROPERTY_YAGO_LABEL );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_LABEL_CLASS.CLASS_NAME,SchemaDefinition.YAGO_LABEL_CLASS.PROPERTY_YAGO_TYPE );
        success &= createSchema(sql);

        //create index YAGO_LABEL.rid on YAGO_LABEL(@rid) NOTUNIQUE METADATA {ignoreNullValues: true}

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_LABEL_CLASS.CLASS_NAME, "rid",
                SchemaDefinition.YAGO_LABEL_CLASS.CLASS_NAME, "@rid");
        success &= createSchema(sql);

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_LABEL_CLASS.CLASS_NAME, SchemaDefinition.YAGO_LABEL_CLASS.PROPERTY_YAGO_ID,
                SchemaDefinition.YAGO_LABEL_CLASS.CLASS_NAME, SchemaDefinition.YAGO_LABEL_CLASS.PROPERTY_YAGO_ID);
        success &= createSchema(sql);

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) FULLTEXT ENGINE LUCENE METADATA {\n" +
                        "                \"analyzer\": \"org.apache.lucene.analysis.en.EnglishAnalyzer\"\n" +
                        "            }",
                SchemaDefinition.YAGO_LABEL_CLASS.CLASS_NAME, SchemaDefinition.YAGO_LABEL_CLASS.PROPERTY_YAGO_LABEL,
                SchemaDefinition.YAGO_LABEL_CLASS.CLASS_NAME, SchemaDefinition.YAGO_LABEL_CLASS.PROPERTY_YAGO_LABEL);
        success &= createSchema(sql);

        return success;
    }

    public boolean createYAGO_LABEL_EDGE(){
        boolean success = true;
        String sql = "";

        sql = String.format("CREATE CLASS %s EXTENDS E", SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME);
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME,SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_ID );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME,SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_LABEL );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME,SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_TYPE );
        success &= createSchema(sql);

        //create index YAGO_LABEL.rid on YAGO_LABEL(@rid) NOTUNIQUE METADATA {ignoreNullValues: true}

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME, "rid",
                SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME, "@rid");
        success &= createSchema(sql);

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME, SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_ID,
                SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME, SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_ID);
        success &= createSchema(sql);

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) FULLTEXT ENGINE LUCENE METADATA {\n" +
                        "                \"analyzer\": \"org.apache.lucene.analysis.en.EnglishAnalyzer\"\n" +
                        "            }",
                SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME, SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_LABEL,
                SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME, SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_LABEL);
        success &= createSchema(sql);

        return success;
    }



    /*
    CONCEPT
     */
    public boolean createYAGO_CONCEPT_CLASS(){
        boolean success = true;
        String sql = "";

        sql = String.format("CREATE CLASS %s EXTENDS V", SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME);
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME,SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_ID );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME,SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_LABEL );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME,SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_TYPE );
        success &= createSchema(sql);

        //create index YAGO_LABEL.rid on YAGO_LABEL(@rid) NOTUNIQUE METADATA {ignoreNullValues: true}

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME, "rid",
                SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME, "@rid");
        success &= createSchema(sql);

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME, SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_ID,
                SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME, SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_ID);
        success &= createSchema(sql);

        /*
        sql = String.format("CREATE INDEX %s.%s ON %s(%s) FULLTEXT ENGINE LUCENE METADATA {\n" +
                        "                \"analyzer\": \"org.apache.lucene.analysis.en.EnglishAnalyzer\"\n" +
                        "            }",
                SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME, SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_LABEL,
                SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME, SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_LABEL);
        success &= createSchema(sql);
        */

        return success;
    }

    public boolean createYAGO_CONCEPT_EDGE(){
        boolean success = true;
        String sql = "";

        sql = String.format("CREATE CLASS %s EXTENDS E", SchemaDefinition.YAGO_CONCEPT_EDGE.EDGE_NAME);
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_CONCEPT_EDGE.EDGE_NAME,SchemaDefinition.YAGO_CONCEPT_EDGE.PROPERTY_YAGO_ID );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_CONCEPT_EDGE.EDGE_NAME,SchemaDefinition.YAGO_CONCEPT_EDGE.PROPERTY_YAGO_LABEL );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_CONCEPT_EDGE.EDGE_NAME,SchemaDefinition.YAGO_CONCEPT_EDGE.PROPERTY_YAGO_TYPE );
        success &= createSchema(sql);

        //create index YAGO_LABEL.rid on YAGO_LABEL(@rid) NOTUNIQUE METADATA {ignoreNullValues: true}

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_CONCEPT_EDGE.EDGE_NAME, "rid",
                SchemaDefinition.YAGO_CONCEPT_EDGE.EDGE_NAME, "@rid");
        success &= createSchema(sql);

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_CONCEPT_EDGE.EDGE_NAME, SchemaDefinition.YAGO_CONCEPT_EDGE.PROPERTY_YAGO_ID,
                SchemaDefinition.YAGO_CONCEPT_EDGE.EDGE_NAME, SchemaDefinition.YAGO_CONCEPT_EDGE.PROPERTY_YAGO_ID);
        success &= createSchema(sql);

        /*
        sql = String.format("CREATE INDEX %s.%s ON %s(%s) FULLTEXT ENGINE LUCENE METADATA {\n" +
                        "                \"analyzer\": \"org.apache.lucene.analysis.en.EnglishAnalyzer\"\n" +
                        "            }",
                SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME, SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_LABEL,
                SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME, SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_LABEL);
        success &= createSchema(sql);
        */

        return success;
    }

    /*
    OTHER
     */
    public boolean createYAGO_OTHER_CLASS(){
        boolean success = true;
        String sql = "";

        sql = String.format("CREATE CLASS %s EXTENDS V", SchemaDefinition.YAGO_OTHER_CLASS.CLASS_NAME);
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_OTHER_CLASS.CLASS_NAME,SchemaDefinition.YAGO_OTHER_CLASS.PROPERTY_YAGO_ID );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_OTHER_CLASS.CLASS_NAME,SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_LABEL );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_OTHER_CLASS.CLASS_NAME,SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_TYPE );
        success &= createSchema(sql);

        //create index YAGO_LABEL.rid on YAGO_LABEL(@rid) NOTUNIQUE METADATA {ignoreNullValues: true}

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_OTHER_CLASS.CLASS_NAME, "rid",
                SchemaDefinition.YAGO_OTHER_CLASS.CLASS_NAME, "@rid");
        success &= createSchema(sql);

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_OTHER_CLASS.CLASS_NAME, SchemaDefinition.YAGO_OTHER_CLASS.PROPERTY_YAGO_ID,
                SchemaDefinition.YAGO_OTHER_CLASS.CLASS_NAME, SchemaDefinition.YAGO_OTHER_CLASS.PROPERTY_YAGO_ID);
        success &= createSchema(sql);

        /*
        sql = String.format("CREATE INDEX %s.%s ON %s(%s) FULLTEXT ENGINE LUCENE METADATA {\n" +
                        "                \"analyzer\": \"org.apache.lucene.analysis.en.EnglishAnalyzer\"\n" +
                        "            }",
                SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME, SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_LABEL,
                SchemaDefinition.YAGO_CONCEPT_CLASS.CLASS_NAME, SchemaDefinition.YAGO_CONCEPT_CLASS.PROPERTY_YAGO_LABEL);
        success &= createSchema(sql);
        */

        return success;
    }

    public boolean createYAGO_OTHER_EDGE(){
        boolean success = true;
        String sql = "";

        sql = String.format("CREATE CLASS %s EXTENDS E", SchemaDefinition.YAGO_OTHER_EDGE.EDGE_NAME);
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_OTHER_EDGE.EDGE_NAME,SchemaDefinition.YAGO_OTHER_EDGE.PROPERTY_YAGO_ID );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_OTHER_EDGE.EDGE_NAME,SchemaDefinition.YAGO_OTHER_EDGE.PROPERTY_YAGO_LABEL );
        success &= createSchema(sql);

        sql = String.format("CREATE PROPERTY %s.%s String",SchemaDefinition.YAGO_OTHER_EDGE.EDGE_NAME,SchemaDefinition.YAGO_OTHER_EDGE.PROPERTY_YAGO_TYPE );
        success &= createSchema(sql);

        //create index YAGO_LABEL.rid on YAGO_LABEL(@rid) NOTUNIQUE METADATA {ignoreNullValues: true}

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_OTHER_EDGE.EDGE_NAME, "rid",
                SchemaDefinition.YAGO_OTHER_EDGE.EDGE_NAME, "@rid");
        success &= createSchema(sql);

        sql = String.format("CREATE INDEX %s.%s ON %s(%s) NOTUNIQUE METADATA {ignoreNullValues: true}",
                SchemaDefinition.YAGO_OTHER_EDGE.EDGE_NAME, SchemaDefinition.YAGO_OTHER_EDGE.PROPERTY_YAGO_ID,
                SchemaDefinition.YAGO_OTHER_EDGE.EDGE_NAME, SchemaDefinition.YAGO_OTHER_EDGE.PROPERTY_YAGO_ID);
        success &= createSchema(sql);

        /*
        sql = String.format("CREATE INDEX %s.%s ON %s(%s) FULLTEXT ENGINE LUCENE METADATA {\n" +
                        "                \"analyzer\": \"org.apache.lucene.analysis.en.EnglishAnalyzer\"\n" +
                        "            }",
                SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME, SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_LABEL,
                SchemaDefinition.YAGO_LABEL_EDGE.EDGE_NAME, SchemaDefinition.YAGO_LABEL_EDGE.PROPERTY_YAGO_LABEL);
        success &= createSchema(sql);
        */

        return success;
    }


    public boolean createSchema(){
        boolean success = true;

        success &= createYAGO_CONCEPT_CLASS();
        success &= createYAGO_CONCEPT_EDGE();

        success &= createYAGO_LABEL_CLASS();
        success &= createYAGO_LABEL_EDGE();

        success &= createYAGO_OTHER_CLASS();
        success &= createYAGO_OTHER_EDGE();

        return success;
    }
}
